/*
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this program. If
 * not, see <http://www.gnu.org/licenses/>.
 */

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

/**
 * 从代码库（需先同步）中扫描所有.asm文件，生成Markdown语法的索引文本。格式为：文件超链接，开头注释（不包括许可证部分)。每次运行时，将当前索引添加到{@link 无索引部分文件名}
 * 末尾，更新README.md
 */
public class 索引生成器 {

  private static final String 代码库基地址 = "http://git.oschina.net/zhishi/asm_for_all/blob/master/";
  private static final String 代码库路径 = "../../";
  private static final List<String> 汇编扩展名 = Arrays.asList(".asm", ".inc");
  // 假设所有注释行开头都是 ;
  private static final String 注释头 = ";";
  // Markdown换行为行尾两个空格
  private static final String 换行 = "  ";
  // 源码规范：开头为许可证块
  private static final int 许可证行数 = 12;
  private static final String 无索引部分文件名 = "READMEwithoutIndex.md";
  private static final String 主页说明文件名 = "README.md";
  // README.md文件输出
  private static Writer 说明文件输出;

  public static void main(String[] args) {
    try {
      初始化说明文件();
      扫描路径(new File(代码库路径));
      说明文件输出.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private static void 扫描路径(File 文件路径) throws Exception {
    if (文件路径.isFile()) {
      if (汇编扩展名.indexOf(取扩展名(文件路径.getName())) > -1) {
        分析源码(文件路径);
      }
    } else if (文件路径.isDirectory()) {
      for (File file : 文件路径.listFiles()) {
        扫描路径(file);
      }
    }
  }

  private static Object 取扩展名(String 文件名) {
    return 文件名.lastIndexOf(".") != -1 ? 文件名.substring(文件名.lastIndexOf(".")).toLowerCase() : "";
  }

  private static void 分析源码(File 文件) throws Exception {
    List<String> 所有行 = 读行(文件);
    List<String> 程序说明 = new ArrayList<>();
    boolean 许可证开始 = false;
    for (int 行号 = 0; 行号 < 所有行.size(); 行号++) {
      String 行 = 所有行.get(行号);
      // 跳过许可证块之前所有空行或无内容的注释行
      if (!许可证开始) {
        if (!取注释内容(行).equals("")) {
          行号 += 许可证行数;
          许可证开始 = true;
        }
        continue;
      }
      // 跳过许可证后所有空行或无内容的注释行
      if (!取注释内容(行).equals("")) {
        if (行.startsWith(注释头)) {
          // 跳过无内容的注释行
          String 注释行内容 = 取注释内容(行);
          if (!注释行内容.equals("")) {
            程序说明.add(注释行内容 + 换行);
          }
        } else {
          break;
        }
      }
    }

    说明文件输出.append("[" + 文件.getName() + "]" + "(" + 代码库基地址 + 文件.getPath().substring(代码库路径.length())
        + ")" + 换行 + "\n" + String.join("\n", 程序说明) + (程序说明.isEmpty() ? "" : "\n") + "\n");
  }

  private static String 取注释内容(String 注释行) {
    return 注释行.replaceFirst("^" + 注释头, "").trim();
  }

  private static List<String> 读行(File 文件) throws Exception {
    final List<String> 所有行 = new ArrayList<>();
    Files.lines(文件.toPath()).forEach(new Consumer<String>() {

      @Override
      public void accept(String 行) {
        所有行.add(行);
      }

    });
    return 所有行;
  }

  private static void 初始化说明文件() throws Exception {
    说明文件输出 = new BufferedWriter(new FileWriter(代码库路径 + 主页说明文件名));
    for (String 行 : 读行(new File(代码库路径 + 无索引部分文件名))) {
      说明文件输出.append(行 + "\n");
    }
  }
}
